import 'dart:async';

import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
import 'package:coordtransform/coordtransform.dart';
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';

import '../../contract.dart';
import 'bean/location_bean.dart';

/// 定位成功
typedef LocationSuccess = Function(LocationBean locationBean);

/// 定位失败
typedef LocationFail = Function(LocationFailBean failBean);

/// 高德定位control
class AmapLocationControl {
  late AMapFlutterLocation _location;
  StreamSubscription<Map<String, Object>>? _locationListener;
  bool _isStart = false;
  LocationSuccess? locationSuccess;
  LocationFail? locationFail;

  AmapLocationControl({this.locationSuccess, this.locationFail}) {
    AMapFlutterLocation.updatePrivacyShow(true, true);
    AMapFlutterLocation.updatePrivacyAgree(true);
    AMapFlutterLocation.setApiKey(
        Contract.AMAP_ANDROID_LOCATION_KEY, Contract.AMAP_IOS_LOCATION_KEY);
    _location = AMapFlutterLocation();
    _location.setLocationOption(AMapLocationOption(locationInterval: 3000));

    _locationListener = _location.onLocationChanged().listen((event) {
      dynamic errorCode = event["errorCode"];
      if (errorCode == null) {
        if (locationSuccess != null) {
          var locationBean = LocationBean.fromJson(event);
          var cordResult = CoordTransform.transformGCJ02toWGS84(
              locationBean.longitude!, locationBean.latitude!);
          locationBean.position = Position(cordResult.lon, cordResult.lat);
          locationSuccess!(locationBean);
        }
      } else {
        if (locationFail != null) {
          locationFail!(LocationFailBean.fromJson(event));
        }
      }
    });
  }

  bool get isStart => _isStart;

  void startLocation() {
    if (_isStart) {
      return;
    }
    _isStart = true;
    _location.startLocation();
  }

  void stopLocation() {
    if (!_isStart) {
      return;
    }
    _isStart = false;
    _location.stopLocation();
  }

  void dispose() {
    _locationListener?.cancel();
    _location.stopLocation();
    _location.destroy();
  }
}
